#include <netinet/in.h>
/*
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };

*/
#include <arpa/inet.h>
/*
in_addr_t inet_addr(const char *strptr);
int inet_aton(const char *cp, struct in_addr *inp);
char* inet_ntoa(struct in_addr in);

int inet_pton(inr af, const char *src, void *dst);
const char* inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
INET_ADDRSTRLEN || INET6_ADDRSTRLEN
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    const char *ip = "192.168.101.123";
    int port = atoi("22");

    // 一般初始化流程：
    struct sockaddr_in address; // <netinet/in.h>
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &address.sin_addr);
    address.sin_port = htons(port);

    // 读取地址到日志
    char remote[INET_ADDRSTRLEN];
    const char *new_remote = inet_ntop(AF_INET, &address.sin_addr, remote, INET_ADDRSTRLEN);
    printf("new_remote == remote ?  %d \n", remote == new_remote);  // 显示 1 说明返回的指针和参数中的 dst 相同
    short new_port = ntohs(address.sin_port);
    printf("address: %s\nport: %d\n", remote, new_port);

    // 其他
    in_addr addr_1, addr_2;
    addr_1.s_addr = inet_addr("1.2.3.4");
    addr_2.s_addr = inet_addr("11.22.33.44");
    char *val1 = inet_ntoa(addr_1);
    char *val2 = inet_ntoa(addr_2);
    printf("addr_1: %s\n", val1);
    printf("addr_2: %s\n", val2);
    // 这里输出内容相同是因为 inet_ntoa 将转化结果存在一个静态变量内，所以有不可重入性（指会覆盖）

    return 0;
}